

//#include "rule/out.h"
//#include "rule/element.h"
//#include "rule/iterator.h"

#if 0

#pragma once

#include "variant_types.h"

#if defined(__GNUC__) || defined(__MINGW32__) || defined(__MINGW__)
    #pragma GCC diagnostic push
    #pragma GCC diagnostic ignored "-Weffc++"
#endif


namespace tools
{
    namespace variant_detail
    {
//-----------------------------------------------------------------------------------------
        template<class T>struct Out
        {
            template<class Stream> static void ToString(const void* const value, Stream& ss)
            {
                const T& v = *static_cast<const T*const >(value);
                ss << v;
            }
        private:
            enum { eTYPE = Type2Enum<T>::eTYPE };
        };
//-----------------------------------------------------------------------------------------
        template<>struct Out<SEmpty>
        {
            template<class Stream> static void ToString(const void* const, Stream& ss){ ss << "empty"; }
            static const char* ToString(){ return "empty"; }
        };
//-----------------------------------------------------------------------------------------
        template<>struct Out<bool>
        {
            template<class Stream> static void ToString(const void* const value, Stream& ss)
            {
                const bool& v = *static_cast<const bool*const >(value);
                ss << (v? "true": "false");
            }
        };
//-----------------------------------------------------------------------------------------
        template<>struct Out<V::Byte>
        {
            template<class Stream> static void ToString(const void* const value, Stream& ss)
            {
                const V::Byte& v = *static_cast<const V::Byte*const >(value);
                ss << "'"<<v<<"'";
            }
        };
//-----------------------------------------------------------------------------------------
        template<>struct Out<V::WChar>
        {
            template<class Stream> static void ToString(const void* const value, Stream& ss)
            {
                const V::Byte& v = *static_cast<const V::Byte*const >(value);
                ss << "'"<<v<<"'";
            }
        };
//-----------------------------------------------------------------------------------------
        template<>struct Out<V::I8>
        {
            template<class Stream> static void ToString(const void* const value, Stream& ss)
            {
                const V::I8& v = *static_cast<const V::I8*const >(value);
                ss << static_cast<int>(v);
            }
        };
//-----------------------------------------------------------------------------------------
        template<>struct Out<V::U8>
        {
            template<class Stream> static void ToString(const void* const value, Stream& ss)
            {
                const V::U8& v = *static_cast<const V::U8*const >(value);
                ss << static_cast<unsigned int>(v);
            }
        };
//-----------------------------------------------------------------------------------------
        template<>struct Out<V::Blob>
        {
            template<class Stream> static void ToString(const void* const value, Stream& ss)
            {
                const V::Blob& v = *static_cast<const V::Blob*const >(value);
                ss << "blob("<< v.size()<<")";
            }
        };
//-----------------------------------------------------------------------------------------
        template<>struct Out<V::Str>
        {
            template<class Stream> static void ToString(const void* const value, Stream& ss)
            {
                const V::Str& v = *static_cast<const V::Str*const >(value);
                ss << "\""<< v.c_str() <<"\"";
            }
        };
//-----------------------------------------------------------------------------------------
        template<>struct Out<V::WStr>
        {
            template<class Stream> static void ToString(const void* const value, Stream& ss)
            {
                const V::WStr& v = *static_cast<const V::WStr*const >(value);
                ss << "\""<< v.c_str() <<"\"";
            }
        };
//-----------------------------------------------------------------------------------------
        template<>struct Out<V::Record>
        {
            template<class Stream> static void ToString(const void* const value, Stream& ss)
            {
                const V::Record& v = *static_cast<const V::Record*const >(value);
                ss << "<\""<< v.first <<"\", "<< v.second.ToString()<<">";
            }
        };
//-----------------------------------------------------------------------------------------
        template<>struct Out<V::Map>
        {
            template<class Stream> static void ToString(const void* const, Stream& ss){ ss << "map"; }
        };
        template<>struct Out<V::Vec>
        {
            template<class Stream> static void ToString(const void* const, Stream& ss){ ss << "vec"; }
        };
        template<>struct Out<V::List>
        {
            template<class Stream> static void ToString(const void* const, Stream& ss){ ss << "list"; }
        };
        template<>struct Out<V::Records>
        {
            template<class Stream> static void ToString(const void* const, Stream& ss){ ss << "records"; }
        };
//-----------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------
        struct Dimmy
        {
            typedef V::Str Str;
            static Str& Default() { static Str s; return s; }
        };
//-----------------------------------------------------------------------------------------
        template<class T, int TYPE_CATEGORY>struct GetElement;
//-----------------------------------------------------------------------------------------

        template<class T>struct GetElement<T,ePRIMITIVE>:Dimmy
        {
            typedef primitive::Iterator
                Iterator;
            typedef primitive::ConstIterator
                ConstIterator;
            typedef primitive::ReverseIterator
                ReverseIterator;
            typedef primitive::ConstReverseIterator
                ConstReverseIterator;

            template<class U, class V> static U CreateIterator(V& var, const bool beg)
            {
                U it(var);
                if(beg)
                    return it;
                ++it;
                    return it;
            }

            static Iterator GetIterator(Variant& var, const bool beg)
            {
                return CreateIterator<Iterator, Variant>(var, beg);
            }
            static ReverseIterator GetReverseIterator(Variant& var, const bool beg)
            {
                return CreateIterator<ReverseIterator, Variant>(var, beg);
            }
            static ConstIterator GetConstIterator(Variant& var, const bool beg)
            {
                return CreateIterator<ConstIterator, Variant>(var, beg);
            }
            static ConstIterator GetConstIterator(const Variant& var, const bool beg)
            {
                return CreateIterator<ConstIterator, const Variant>(var, beg);
            }
            static ConstReverseIterator GetConstReverseIterator(Variant& var, const bool beg)
            {
                return CreateIterator<ConstReverseIterator, Variant>(var, beg);
            }
            static ConstReverseIterator GetConstReverseIterator(const Variant& var, const bool beg)
            {
                return CreateIterator<ConstReverseIterator, const Variant>(var, beg);
            }

            static const Str& GetKey(const void* const){ return Default(); }
            static const Variant& GetVariant(const void* const data)
                { return *static_cast<const Variant*>(data); }
        };
//-----------------------------------------------------------------------------------------
        template<class T>struct GetElement<T,eLINEAR>:Dimmy
        {
            typedef V::Str Str;

            typedef typename T::iterator
                Iterator;
            typedef typename T::const_iterator
                ConstIterator;
            typedef typename T::reverse_iterator
                ReverseIterator;
            typedef typename T::const_reverse_iterator
                ConstReverseIterator;

            static Iterator GetIterator(Variant& var, const bool beg)
            {
                auto& lenear = var.template Get<T>();
                return beg? lenear.begin(): lenear.end();
            }
            static ReverseIterator GetReverseIterator(Variant& var, const bool beg)
            {
                auto& lenear = var.template Get<T>();
                return beg? lenear.rbegin(): lenear.rend();
            }
            static ConstIterator GetConstIterator(Variant& var, const bool beg)
            {
                auto& lenear = var.template Get<T>();
                return beg? lenear.cbegin(): lenear.cend();
            }
            static ConstIterator GetConstIterator(const Variant& var, const bool beg)
            {
                auto& lenear = var.template Get<T>();
                return beg? lenear.cbegin(): lenear.cend();
            }
            static ConstReverseIterator GetConstReverseIterator(Variant& var, const bool beg)
            {
                auto& lenear = var.template Get<T>();
                return beg? lenear.crbegin(): lenear.crend();
            }
            static ConstReverseIterator GetConstReverseIterator(const Variant& var, const bool beg)
            {
                auto& lenear = var.template Get<T>();
                return beg? lenear.crbegin(): lenear.crend();
            }

            static const Str& GetKey(const void* const){ return Default(); }
            static const Variant& GetVariant(const void* const data)
            {
                return *static_cast<const Variant*>(data);
            }
        };
//-----------------------------------------------------------------------------------------
        template<class T>struct GetElement<T,eASSOCIATIVE>:Dimmy
        {
            typedef typename T::iterator
                Iterator;
            typedef typename T::const_iterator
                ConstIterator;
            typedef typename T::reverse_iterator
                ReverseIterator;
            typedef typename T::const_reverse_iterator
                ConstReverseIterator;
            typedef typename T::value_type
                ValueType;

            static Iterator GetIterator(Variant& var, const bool beg)
            {
                auto& lenear = var.template Get<T>();
                return beg? lenear.begin(): lenear.end();
            }
            static ReverseIterator GetReverseIterator(Variant& var, const bool beg)
            {
                auto& lenear = var.template Get<T>();
                return beg? lenear.rbegin(): lenear.rend();
            }
            static ConstIterator GetConstIterator(Variant& var, const bool beg)
            {
                auto& lenear = var.template Get<T>();
                return beg? lenear.cbegin(): lenear.cend();
            }
            static ConstIterator GetConstIterator(const Variant& var, const bool beg)
            {
                auto& lenear = var.template Get<T>();
                return beg? lenear.cbegin(): lenear.cend();
            }
            static ConstReverseIterator GetConstReverseIterator(Variant& var, const bool beg)
            {
                auto& lenear = var.template Get<T>();
                return beg? lenear.crbegin(): lenear.crend();
            }
            static ConstReverseIterator GetConstReverseIterator(const Variant& var, const bool beg)
            {
                auto& lenear = var.template Get<T>();
                return beg? lenear.crbegin(): lenear.crend();
            }

            static const Str& GetKey(const void* const data)
            {
                const ValueType& pair = *static_cast<const ValueType*const>(data);
                return pair.first;
            }
            static const Variant& GetVariant(const void* const data)
            {
                const ValueType& pair = *static_cast<const ValueType*const>(data);
                return pair.second;
            }
        };
//-----------------------------------------------------------------------------------------
        template<class T>struct GetElement<T,eKEY_VARIANT>:Dimmy
        {
            typedef typename T::value_type
                ValueType;

            static const Str& GetKey(const void* const data)
            {
                const ValueType& pair = *static_cast<const ValueType*const>(data);
                return pair.first;
            }

            static const Variant& GetVariant(const void* const data)
            {
                const ValueType& pair = *static_cast<const ValueType*const>(data);
                return pair.second;
            }
        };
//-----------------------------------------------------------------------------------------

    }//namespace value_detail
}//namespace tools


#if defined(__GNUC__) || defined(__MINGW32__) || defined(__MINGW__)
    #pragma GCC diagnostic pop
#endif
#endif
